package gui;

import image.Drawing;
import javafx.animation.FadeTransition;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.Separator;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.effect.InnerShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.util.Duration;

/**
 * A toolbar that enables to switch controls as well as 
 */
public class ToolBar extends javafx.scene.control.ToolBar
{
	private final Settings settings; // reference to Main settings
	private final Orientation orientation = Orientation.VERTICAL;
	public static final int WIDTH = 175;
	public static final int HEIGHT = 500;
			
	private final Image imageEllipse = new Image(getClass().getResourceAsStream("ellipse.png"));
	private final Image imageRectangle = new Image(getClass().getResourceAsStream("rectangle.png"));
	private final Image imageTriangle = new Image(getClass().getResourceAsStream("triangle.png"));
	private final Image imageLine = new Image(getClass().getResourceAsStream("line.png"));
	private final Image imageText = new Image(getClass().getResourceAsStream("text.png"));
	private final Image imageColor = new Image(getClass().getResourceAsStream("color_swatch.png"));
	private final Image imageResize = new Image(getClass().getResourceAsStream("layer_resize.png"));
	private final Image imageDrag = new Image(getClass().getResourceAsStream("drag.png"));
	private final Image imageDelete = new Image(getClass().getResourceAsStream("eraser.png"));
	private final Image imageLineRot = new Image(getClass().getResourceAsStream("rotate.png"));
	
	private final ToggleGroup toggleGroup = new ToggleGroup();
	
	private final ToggleButton buttonRectangle = new ToggleButton("Rectangle");
	private final ToggleButton buttonEllipse = new ToggleButton("Ellipse");
	private final ToggleButton buttonTriangle = new ToggleButton("Triangle");
	private final ToggleButton buttonLine = new ToggleButton("Line");
	private final ToggleButton buttonText = new ToggleButton("Text");
	private ColorPicker buttonForeColor = new ColorPicker();
	private final ColorPicker buttonBackColor = new ColorPicker();
	private final Slider lineSlider = new Slider();
	private final ToggleButton buttonModify = new ToggleButton("Modify");
	private final ToggleButton buttonResize = new ToggleButton("Resize");
	private final ToggleButton buttonDrag = new ToggleButton("Drag");
	private final ToggleButton buttonDelete = new ToggleButton("Delete");
	private final ToggleButton buttonLineRot = new ToggleButton("Rotation");
	private final ToggleButton buttonTimer = new ToggleButton("Start Task");
	
	// ==========Timer
	KTimer ktimer = new KTimer();
	
	public ToolBar(final Settings s)
	{
		super();
		this.setOrientation(orientation);
		this.setPrefWidth(WIDTH);
		this.setPrefHeight(HEIGHT);
		this.setStyle("-fx-background-color: " + Main.getBackground() + "; -fx-border-color: #888888");
		
		buttonRectangle.setGraphic(new ImageView(imageRectangle));
		buttonRectangle.setPrefHeight(35);
		buttonRectangle.setPrefWidth(100);
		buttonRectangle.setToggleGroup(toggleGroup);
		buttonRectangle.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent event)
			{
				s.setMode(Mode.Rectangle);
				flash(buttonRectangle, " You are now drawing a rectangle");
				// TODO: Ik ben een functie voor de button genaamd "Rectangle"
			}
		});
		
		buttonEllipse.setGraphic(new ImageView(imageEllipse));
		buttonEllipse.setPrefHeight(35);
		buttonEllipse.setPrefWidth(100);
		buttonEllipse.setToggleGroup(toggleGroup);
		buttonEllipse.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent event)
			{
				s.setMode(Mode.Ellipse);
				flash(buttonEllipse, "You are now drawing an Ellipse");
				// TODO: Ik ben een functie voor de button genaamd "Ellipse"
			}
		});
		
		buttonTriangle.setGraphic(new ImageView(imageTriangle));
		buttonTriangle.setPrefHeight(35);
		buttonTriangle.setPrefWidth(100);
		buttonTriangle.setToggleGroup(toggleGroup);
		buttonTriangle.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent event)
			{
				s.setMode(Mode.Triangle);
				flash(buttonTriangle, " You are now drawing a triangle");
				// TODO: Ik ben een functie voor de button genaamd "Triangle"
			}
		});
		
		buttonLine.setGraphic(new ImageView(imageLine));
		buttonLine.setPrefHeight(35);
		buttonLine.setPrefWidth(100);
		buttonLine.setToggleGroup(toggleGroup);
		buttonLine.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent event)
			{
				s.setMode(Mode.Line);
				flash(buttonLine, " You are now drawing a line");
				// TODO: Ik ben een functie voor de button genaamd "Line"
			}
		});
		
		buttonText.setGraphic(new ImageView(imageText));
		buttonText.setPrefHeight(35);
		buttonText.setPrefWidth(100);
		buttonText.setToggleGroup(toggleGroup);
		buttonText.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent event)
			{
				s.setMode(Mode.Text);
				flash(buttonText, " You can now type text");
				//tekstveld
				// TODO: Ik ben een functie voor de button genaamd "Text"
				
			}
		});
		
		
		Separator color_separator = new Separator();
		color_separator.setOrientation(Orientation.HORIZONTAL);
		
		Separator line_separator = new Separator();
		line_separator.setOrientation(Orientation.HORIZONTAL);
		
		Separator task_separator = new Separator();
		task_separator.setOrientation(Orientation.HORIZONTAL);
		
		Separator modify_separator = new Separator();
		modify_separator.setOrientation(Orientation.HORIZONTAL);
		
		// ========== Colors
		
		VBox colorBox = new VBox(10);
//		colorBox.setStyle("-fx-border-style: solid;"
//                + "-fx-border-width: 1;"
//                + "-fx-border-color: black");
		
		InnerShadow innerShadow = new InnerShadow();
		innerShadow.setColor(Color.BLACK);
		innerShadow.setWidth(10);
		innerShadow.setHeight(10);

		HBox foreBox = new HBox(10);
		foreBox.setAlignment(Pos.CENTER_LEFT);
		Text textForeColor = new Text("Line / Border");
		textForeColor.setSmooth(true);
		textForeColor.setEffect(innerShadow);
		buttonForeColor.setValue((Color)s.getForeColor());
		buttonForeColor.setPrefHeight(35);
		buttonForeColor.setPrefWidth(90);
		
		buttonForeColor.valueProperty().addListener(new ChangeListener<Color>() {
			@Override public void changed(ObservableValue<? extends Color> observable, Color oldValue, Color newValue) 
			{
				s.setForeColor(newValue);
			}
		});

		foreBox.getChildren().addAll(buttonForeColor, textForeColor);
		
		HBox backBox = new HBox(10);
		backBox.setAlignment(Pos.CENTER_LEFT);
		Text textBackColor = new Text("Background");
		buttonBackColor.setValue((Color) s.getBackColor());
		buttonBackColor.setPrefHeight(35);
		buttonBackColor.setPrefWidth(90);
		buttonBackColor.valueProperty().addListener(new ChangeListener<Color>() {
			@Override public void changed(ObservableValue<? extends Color> observable, Color oldValue, Color newValue) 
			{
				s.setBackColor(newValue);
			}
		});
		backBox.getChildren().addAll(buttonBackColor, textBackColor);
		
		colorBox.getChildren().addAll(foreBox, backBox);
		
		// =====================
		
		lineSlider.setPrefSize(100, 35);
		lineSlider.setMajorTickUnit(1.0);
		lineSlider.setShowTickLabels(true);
		lineSlider.setMax(10.0);
		lineSlider.setMin(0.0);
		lineSlider.setValue(s.getStrokeWidth());
		lineSlider.valueProperty().addListener(new ChangeListener<Number>() {
			@Override public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2)
			{
				s.setStrokeWidth(arg2.doubleValue());
			}
		});
		
		buttonModify.setGraphic(new ImageView(imageDrag));
		buttonModify.setPrefHeight(35);
		buttonModify.setPrefWidth(100);
		buttonModify.setToggleGroup(toggleGroup);
		buttonModify.setOnAction(new EventHandler<ActionEvent> () {
			@Override public void handle(ActionEvent event)
			{
				s.setMode(Mode.Modify);
				flash(buttonModify, "You can now modify your drawings - Select the desired layer you want to edit now", 4000);
			}
		});
		
		buttonResize.setGraphic(new ImageView(imageResize));
		buttonResize.setPrefHeight(35);
		buttonResize.setPrefWidth(100);
		buttonResize.setToggleGroup(toggleGroup);
		buttonResize.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent event)
			{
				s.setMode(Mode.Resize);
				flash(buttonResize, " You can now resize your drawings");
			}
		});
		
		buttonDrag.setGraphic(new ImageView(imageDrag));
		buttonDrag.setPrefHeight(35);
		buttonDrag.setPrefWidth(100);
		buttonDrag.setToggleGroup(toggleGroup);
		buttonDrag.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent event)
			{
				s.setMode(Mode.Drag);
				flash(buttonDrag, " Once you select the Layer you want to move, you may drag around your object", 4000);
			}
		});
		
		buttonDelete.setGraphic(new ImageView(imageDelete));
		buttonDelete.setPrefHeight(35);
		buttonDelete.setPrefWidth(100);
		buttonDelete.setToggleGroup(toggleGroup);
		buttonDelete.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent event)
			{
				s.setMode(Mode.Delete);
				flash(buttonDelete, " You can now delete your faulty drawings");
			}
		});
		
		buttonLineRot.setGraphic(new ImageView(imageLineRot));
		buttonLineRot.setPrefHeight(35);
		buttonLineRot.setPrefWidth(100);
		buttonLineRot.setToggleGroup(toggleGroup);
		buttonLineRot.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent event)
			{
				s.setMode(Mode.Rotate);
				flash(buttonLineRot, " You can now rotate that line");
			}
		});
		
		buttonTimer.setGraphic(new ImageView(imageLineRot));
		buttonTimer.setPrefHeight(35);
		buttonTimer.setPrefWidth(100);
		buttonTimer.setToggleGroup(toggleGroup);
		buttonTimer.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent event)
			{
				if (Main.getKTimer().startedProperty().get())
					Main.getKTimer().stopTimer();
				else
					Main.getKTimer().startTimer(0);
			}
		});
		Main.getKTimer().startedProperty().addListener(new ChangeListener<Boolean> () {
			@Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue)
			{
				if (newValue)
				{
					// Switching from "Started" to "Stopped"
					buttonTimer.setText("Stop Task");
					buttonTimer.requestFocus();
					buttonTimer.setSelected(true);
					flash(buttonTimer, " Task Started - Timer is now running");
				}
				else
				{	// Switching from "Stopped" to "Started"
					buttonTimer.setText("Start Task");
					buttonTimer.setSelected(false);
					flash(buttonTimer, " Task Ended - Time elapsed was " + Main.getKTimer().timeStringProperty().get(), 2000);
				}
			}
		});
		
		this.getItems().addAll(buttonRectangle, buttonEllipse, buttonTriangle, buttonLine, buttonText, modify_separator, buttonModify); //, buttonResize, buttonDrag, buttonDelete, buttonLineRot);
		this.getItems().addAll(color_separator, colorBox, line_separator, lineSlider, task_separator, buttonTimer);
		settings = s;
	}
	
	public void flash(Node node, String msg)
	{
		flash(node, msg, 1500);
	}
	
	public void flash(Node node, String message, double duration) {
        Font font = Font.font("Verdana", FontWeight.NORMAL, 20);
        Color boxColor = Color.BLACK;
        Color textColor = Color.AQUA;
        double arcH = 5;
        double arcW = 5;
 
        final Rectangle rectangle = new Rectangle();
        final Text text = new Text(message);
  
        double x = 0;
        double y = 0;
        text.setLayoutX(x);
        text.setLayoutY(y);
        text.setFont(font);
        text.setFill(textColor);
 
        Scene scene = node.getScene();
        final Parent p = scene.getRoot();
 
        if (p instanceof Group) 
        {
            Group group = (Group) p;
            group.getChildren().add(rectangle);
            group.getChildren().add(text);
        }
        if (p instanceof Pane) 
        {
            Pane group = (Pane) p; 
            group.getChildren().add(rectangle);
            group.getChildren().add(text);
        }
 
        double sWidth = scene.getWidth();
        double sHeight = scene.getHeight();
 
        x = sWidth / 2 - text.getLayoutBounds().getWidth() / 2;
        y = sHeight / 2 - text.getLayoutBounds().getHeight() / 2;
        text.setManaged(false);
        text.setLayoutX(x);
        text.setLayoutY(y);
 
        rectangle.setFill(boxColor);
        rectangle.setManaged(false);
        rectangle.setLayoutX(x);
        rectangle.setLayoutY(y - text.getLayoutBounds().getHeight());
        rectangle.setArcHeight(arcH);
        rectangle.setArcWidth(arcW);
        rectangle.setWidth(text.getLayoutBounds().getWidth() + arcW * 2);
        rectangle.setHeight(text.getLayoutBounds().getHeight() + arcH * 2);
 
        FadeTransition ft = new FadeTransition(Duration.millis(duration), rectangle);
        ft.setFromValue(1.0);
        ft.setToValue(0.0);
        ft.play();
        ft.setOnFinished(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent event) {
                if (p instanceof Group) {
                    Group group = (Group) p;
                    group.getChildren().remove(rectangle);
                    group.getChildren().remove(text);
                }
                 if (p instanceof Pane) {
                    Pane group = (Pane) p;
                    group.getChildren().remove(rectangle);
                    group.getChildren().remove(text);
                }
            }
        });
        FadeTransition ft2 = new FadeTransition(Duration.millis(duration + (duration * .1)), text);
        ft2.setFromValue(1.0);
        ft2.setToValue(0.0);
        ft2.play();
    }
	
	
	/*
	 * public class KeyEventsSample extends Application {
	 

		    private void init(Stage primaryStage) {
	        Group root = new Group();
	        primaryStage.setScene(new Scene(root));
	        //create a console for logging key events
	        final ListView<String> console = new ListView<String>(FXCollections.<String>observableArrayList());
	        // listen on the console items and remove old ones when we get over 10 items
	        console.getItems().addListener(new ListChangeListener<String>() {
	            @Override public void onChanged(Change<? extends String> change) {
	                while (change.next()) {
	                   if (change.getList().size() > 20) change.getList().remove(0);
	                }
	           }
	        });

	        // create text box for typing in
	        final TextField textBox = new TextField();
	        textBox.setPromptText("Write here");
	        textBox.setStyle("-fx-font-size: 34;");
	        //add a key listeners
	        textBox.setOnKeyPressed(new EventHandler<KeyEvent>() {
	            public void handle(KeyEvent ke) {
	               console.getItems().add("Key Pressed: " + ke.getText());
	            }
	        });
	        textBox.setOnKeyReleased(new EventHandler<KeyEvent>() {
	            public void handle(KeyEvent ke) {
	                console.getItems().add("Key Released: " + ke.getText());
	            }
	        });

	        textBox.setOnKeyTyped(new EventHandler<KeyEvent>() {
	            public void handle(KeyEvent ke) {
	                String text = "Key Typed: " + ke.getCharacter();
	                if (ke.isAltDown()) {
	                    text += " , alt down";
	                }
	                if (ke.isControlDown()) {
	                    text += " , ctrl down";
	                }
	                if (ke.isMetaDown()) {
	                    text += " , meta down";
	                }
	                if (ke.isShiftDown()) {
	                    text += " , shift down";
	                }
	                console.getItems().add(text);
	            }
	        });
	        VBox vb = new VBox(10);
	        vb.getChildren().addAll(textBox, console);
	        root.getChildren().add(vb);
	    }
	 

	    @Override public void start(Stage primaryStage) throws Exception {
	        init(primaryStage);
	        primaryStage.show();
	    }

	    public void main(String[] args) { launch(args); }
	}
*/
}
